package lj.netty.bean;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import io.netty.handler.codec.http.*;
import io.netty.util.CharsetUtil;
import lombok.Data;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author: liuwenju
 * @date: 2023/6/20 17:36
 * @version: 1.0
 */
@Data
public class LJNettyHttpContext {

    private FullHttpRequest request;

    public LJNettyHttpContext(FullHttpRequest request) {
        this.request = request;
    }

    public String getParam(String key) {
        String valByUrl = getValByUrl(key);
        if (StrUtil.isBlank(valByUrl)) {
            valByUrl = getValByForm(key);
        }
        if (StrUtil.isBlank(valByUrl)) {
            valByUrl = getValByBody(key);
        }
        return valByUrl;
    }

    public String getValByUrl(String key) {
        QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
        Map<String, List<String>> params = decoder.parameters();
        return params.getOrDefault(key, ListUtil.of(null)).get(0);
    }

    public Map<String, String> getUrlMap() {
        Map<String, String> map = new HashMap<>();
        QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
        Map<String, List<String>> params = decoder.parameters();

        for (Map.Entry<String, List<String>> stringListEntry : params.entrySet()) {
            List<String> value = stringListEntry.getValue();
            if (value.size() > 0) {
                map.put(stringListEntry.getKey(), value.get(0));
            }
        }
        return map;
    }

    public String getValByForm(String key) {
        if (request.method() == HttpMethod.POST && request.headers().contains(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED, true)) {
            String content = request.content().toString(CharsetUtil.UTF_8);
            QueryStringDecoder decoder = new QueryStringDecoder("?" + content);
            Map<String, List<String>> params = decoder.parameters();
            return params.getOrDefault(key, ListUtil.of((String) null)).get(0);
        }
        return null;
    }

    public Map<String, String> getFormMap() {
        Map<String, String> map = new HashMap<>();
        if (request.method() == HttpMethod.POST && request.headers().contains(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_X_WWW_FORM_URLENCODED, true)) {
            String content = request.content().toString(CharsetUtil.UTF_8);
            QueryStringDecoder decoder = new QueryStringDecoder("?" + content);
            Map<String, List<String>> params = decoder.parameters();

            for (Map.Entry<String, List<String>> stringListEntry : params.entrySet()) {
                List<String> value = stringListEntry.getValue();
                if (value.size() > 0) {
                    map.put(stringListEntry.getKey(), value.get(0));
                }
            }
        }
        return map;
    }

    public String getValByBody(String key) {
        if (request.method() == HttpMethod.POST && request.headers().contains(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON, true)) {
            String content = request.content().toString(CharsetUtil.UTF_8);
            JSONObject jsonObject = JSONUtil.parseObj(content);
            if (ObjectUtil.isNotNull(jsonObject)) {
                return jsonObject.getStr(key);
            }
        }
        return null;
    }

    public String body() {
        if (request.method() == HttpMethod.POST && request.headers().contains(HttpHeaderNames.CONTENT_TYPE, HttpHeaderValues.APPLICATION_JSON, true)) {
            return request.content().toString(CharsetUtil.UTF_8);
        }
        return null;
    }

}
